import qs from 'qs';
// https://github.com/axios/axios
import axios from 'axios';
// https://github.com/webmodules/jsonp
const jsonp = require('jsonp');

axios.default.withCredentials = true;

// 转换formData
axios.defaults.transformRequest = [
  (data) => {
    return qs.stringify(data);
  },
];

axios.interceptors.request.use(
  (config) => {
    return config;
  },
  (err) => {
    return Promise.reject(err);
  },
);

/**
 * 数据请求方法
 * @param {object} options 请求参数选项 - 请看axios的参数选项
 * {
 *  method: 'get',  // 请求方法
 *  url: '/v1/user', // 请求链接
 *  params: {}, // url 参数
 *  data: {}, // 请求体中的数据 ‘post’ 请求
 *  isJson: false, // 是否是以json的形式请求数据
 *  ... ...
 * }
 */
export function fetch(options) {
  const { params } = options;
  const paramsConfig = {
    isJson: true,
    method: 'GET',
    withCredentials: false,
    ...options,
    params,
  };

  if (paramsConfig.isJson) {
    paramsConfig.headers = {
      ...options.headers,
      ...{
        'Content-Type': 'application/json',
      },
    };
    paramsConfig.transformRequest = [
      (data) => {
        return JSON.stringify(data);
      },
    ];
  }
  return new Promise((resolve, reject) => {
    axios(paramsConfig)
      .then((res) => {
        resolve(res.data);
      })
      .catch((err) => {
        if (err.response) {
          console.error(paramsConfig.url, err.response.status);
          reject(err);
        } else if (err.message === 'Network Error') {
          console.error('Error', paramsConfig.url, err.message);
          reject(err);
        } else {
          reject(err);
        }
      });
  });
}

/**
 * jsonp 请求
 * @param {string} url 请求连接
 * @param {object} opts 请求参数
 * @param {string} opts.param [default=callback] 查询字符串参数的名称以指定回调
 * @param {string} opts.timeout [default=10000] 发出超时错误后多长时间
 * @param {string} opts.prefix [default=__jp] 用于处理jsonp响应的全局回调函数的前缀
 * @param {string} opts.name [default=opts.prefix + 递增计数] 处理jsonp响应的全局回调函数的名称
 * @return {Promise}
 */
export function fetchJSONP(url, opts) {
  const params = {
    timeout: 10000,
    ...opts,
  };
  return new Promise((resolve, reject) => {
    jsonp(url, params, (err, data) => {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}
